package no.ntnu.fp.su.sensors;

import no.ntnu.fp.su.Flow;
import no.ntnu.fp.su.util.NormalDistribution;

/**
 * An erosion probe. The erosion material values are from Monel 400, as used in at least 1 actual product [0].
 * 
 * The resistivity of Monel 400 at 21 degrees celsius is 5.11*10^-4 ohm-meters [3].
 * 
 * The temperature coefficient of resistance [1] of Monel 400 is assumed to be
 * 0.63*alhpa_nickel + 0.34*alpha_copper + 0.03*alpha_iron, a naive approximation based
 * on Monel 400's composition, since no exact value could be found.
 *
 * [0] http://www.roxar.com/getfile.php/Files/Product%20Datasheets/Topside/DataSheet_SandErosionProbe_VerA_LoRes.pdf
 * [1] http://www.allaboutcircuits.com/vol_1/chpt_12/6.html
 * [2] Y. Zhang, E.P. Reuterfors, B.S. McLaury, S.A. Shirazi, E.F. Rybicki, Comparison of computed and measured particle velocities and erosion in water and air flows, Wear, Volume 263, Issues 1-6, 16th International Conference on Wear of Materials, 10 September 2007, Pages 330-338, ISSN 0043-1648, DOI: 10.1016/j.wear.2006.12.048. (http://www.sciencedirect.com/science/article/B6V5B-4NT57HS-29/2/b886a9ce1a48da5f7886b2a2f1676069)
 * [3] www.specialmetals.com/documents/Monel%20alloy%20400.pdf 
 */
public class ErosionProbe implements Sensor {
	private static double resistivity = 0.000511; // ohm-meters
	private static double temperatureCoefficent = 0.00523965; // alpha/C
	private static double referenceTemperature = 21.0; // C
	private double area = 0.046; // meters^2
	private double temperature; // C
	private double distance = 0.3; // meters
	private Flow flow;
	private double metersFromReservoir;
	public ErosionProbe(Flow flow, double metersFromReservoir) {
		this.flow=flow;
		this.metersFromReservoir=metersFromReservoir;
	}
	@Override
	public double sample() {
		temperature=flow.getTemperature(metersFromReservoir);
		double er = getErosionRatio(165,.53,flow.getVelocity(),0);
		area -= area  * er * flow.getSandContent(); // not physically correct
		return NormalDistribution.sample(resistivity * (distance / area) * (temperatureCoefficent * (temperature - referenceTemperature) + 1.0), 0.00000005);
	}
	/**
	 * Erosion model from [2] pp6.
	 * 
	 * @param brinellHardness For Monel 400, a reasonable assumption would be 165 [3], pp2.
	 * @param particleShapeCoefficient Fs = 1.0 for sharp (angular), 0.53 for semi-rounded, or 0.2 for fully rounded sand particles. [2]
	 * @param particleImpactSpeed particle impact speed in m/s.
	 * @param theta The impact angle in radians.
	 * 
	 * @return Erosion ratio, defined as the amount of mass lost by the wall material due to particle impacts divided by the mass of particles impacting.

	 */	
	private double getErosionRatio(double brinellHardness, double particleShapeCoefficient, double particleImpactSpeed, double theta) {
		double n = 2.41;
		double C = 2.17*Math.pow(10,-7);
		double fTheta=0;
		double[] a = {5.40,-10.11,10.93,-6.33,1.42};
		for(int i=0;i<5;i++) { fTheta+=a[i]*Math.pow(theta,i); }
		return C * Math.pow(brinellHardness,-.59) * particleShapeCoefficient * Math.pow(particleImpactSpeed,n) * fTheta;
	}

}
